#!/usr/bin/php
<?php
include_once( "common.php" );
$file = "gbk.xml";
class CNewsInfo {
    public $id;
    public $date;
    public $title;
    public $path;
    public $url;
    public $text;
    const TYPE = 0x00001000;
    const SUBTYPE = 0x00000011;
    public function __construct()
    {
        $this->id = 0;
        $this->data = "";
        $this->title = "";
        $this->path = "";
        $this->url = "";
        $this->text = "";

        printf("init CNewsInfo\n");
    }
    public function __destruct()
    {
        printf("release CNewsInfo\n");
    }
    public function get_request()
    {
        $request = pack('NNNa32a80a128a256a*'
            , 0x00000000
            , 0x00000011
            , $this->id
            , $this->date
            , $this->title
            , $this->path
            , $this->url
            , $this->text );
        $request = pack('N', strlen($request) + 4 ).$request;
        return $request;
    }
    public function print_obj()
    {
        printf("\tid = %s\n\tdata = %s\n\ttitle = %s\n\tpath = %s\n\turl = %s\n\ttext = %s\n"
            , $this->id
            , $this->date
            , $this->title
            , $this->path
            , $this->url
            , $this->text );
    }
}

class CNewsXMLParser 
{
    const NEWS_ELEMENT_INVLIAD = 0;
    const NEWS_ELEMENT_DOC = 1;
    const NEWS_ELEMENT_ID = 2;
    const NEWS_ELEMENT_DATE = 3;
    const NEWS_ELEMENT_TITLE = 4;
    const NEWS_ELEMENT_PATH = 5;
    const NEWS_ELEMENT_URL = 6;
    const NEWS_ELEMENT_TEXT = 7;
    #const ENCODING = "ISO-8859-1";
    const ENCODING = "UTF-8";

    protected $_m_xmlFileName;
    protected $_m_xmlParser;
    protected static $_m_newsObj;
    protected static $_m_text;
    public static $m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_INVLIAD;
    #public const var $ENCODING="ISO-8859-1";
    public function __construct( $xmlFile )
    {
        printf("construct CNewsXMLParser object.\n");
        $this->_m_xmlFileName = $xmlFile;
        $this->_m_xmlParser = xml_parser_create( CNewsXMLParser::ENCODING );
        $this->__init( );
    }
    public function __destruct( ) 
    {
        printf("xmlFile = %s\n", $this->_m_xmlFileName );
        #printf("ENCODING = %s\n", CNewsXMLParser::ENCODING );
        xml_parser_free( $this->_m_xmlParser );
        printf("destruct CNewsXMLParser.\n");
    }
    public static function send_request( )
    {
        $request = CNewsXMLParser::$_m_newsObj->get_request();
        $header = unpack('N*', substr( $request, 0, 16) );
        print_r($header);
        print_r( unpack('a*', substr($request, 512 ) ) );
        $sock = get_socket();
        socket_set_option( $sock, SOL_SOCKET, SO_LINGER, array("l_onoff"=>1, "l_linger"=>1) );
        socket_write( $sock,  CNewsXMLParser::$_m_newsObj->get_request(), strlen( CNewsXMLParser::$_m_newsObj->get_request()) );
        $buf = socket_read( $sock, 16 );
        $res = unpack('N*', $buf );
        print_r($res);

        socket_close( $sock );
    }
    public function __init( )
    {
        xml_parser_set_option($this->_m_xmlParser, XML_OPTION_CASE_FOLDING, 0); 
        xml_parser_set_option($this->_m_xmlParser, XML_OPTION_SKIP_WHITE, 1); 
        #xml_set_processing_instruction_handler($parser, "pi_handler"); 
        xml_set_default_handler($this->_m_xmlParser, "CNewsXMLParser::default_handler"); 
        xml_set_element_handler($this->_m_xmlParser, "CNewsXMLParser::start_element_handler", "CNewsXMLParser::end_element_handler"); 
        xml_set_character_data_handler($this->_m_xmlParser, "CNewsXMLParser::cdata_handler"); 
        $this->m_newsElementType = $this->NEWS_ELEMENT_INVLIAD;
    }
    public static function default_handler( $parser, $data )
    {
    }
    public static function cdata_handler( $parser, $data0 )
    {
        $data = iconv( "UTF-8", "GBK", $data0 );
        #printf("cdata_handler...\n");
        switch( CNewsXMLParser::$m_newsElementType ) {
        case CNewsXMLParser::NEWS_ELEMENT_DOC:
            break;
        case CNewsXMLParser::NEWS_ELEMENT_ID:
            CNewsXMLParser::$_m_newsObj->id = $data;
            break;
        case CNewsXMLParser::NEWS_ELEMENT_DATE:
            CNewsXMLParser::$_m_newsObj->date = $data;
            break;
        case CNewsXMLParser::NEWS_ELEMENT_TITLE:
            CNewsXMLParser::$_m_newsObj->title = $data;
            break;
        case CNewsXMLParser::NEWS_ELEMENT_PATH:
            CNewsXMLParser::$_m_newsObj->path = $data;
            break;
        case CNewsXMLParser::NEWS_ELEMENT_URL:
            CNewsXMLParser::$_m_newsObj->url = $data;
            break;
        case CNewsXMLParser::NEWS_ELEMENT_TEXT:
            #CNewsXMLParser::$_m_newsObj->text = $data;
            CNewsXMLParser::$_m_text .= $data;
            #printf("text = %s\n", $data );
            #printf("textlen = %d\n", strlen($data) );
            break;
        case CNewsXMLParser::NEWS_ELEMENT_INVLIAD:
        default:
            #printf("invalid new element type : %d\n", CNewsXMLParser::$m_newsElementType );
            
        }
    }
    public static function start_element_handler( $parser, $name, $attrs )
    {
        if( $name == 'doc' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_DOC;
            CNewsXMLParser::$_m_newsObj = new CNewsInfo;
            CNewsXMLParser::$_m_text = "";

        } else if( $name == 'title' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_TITLE;
        } else if( $name == 'docid' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_ID;
        } else if( $name == 'url' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_URL;
        } else if( $name == 'text' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_TEXT;
        } else if( $name == 'datestr' ) {
            CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_DATE;
        }
    }
    public static function end_element_handler( $parser, $name )
    {
        CNewsXMLParser::$m_newsElementType = CNewsXMLParser::NEWS_ELEMENT_INVLIAD;
        if( $name == 'doc' ) {
            CNewsXMLParser::$_m_newsObj->print_obj();
            CNewsXMLParser::$_m_newsObj->text = CNewsXMLParser::$_m_text;
            printf("len = %d\n", strlen(CNewsXMLParser::$_m_newsObj->get_request()));
            CNewsXMLParser::send_request();
        } else if( $name == 'title' ) {
        } 
    }
    public function parse_it( )
    {
        $fp = fopen( $this->_m_xmlFileName, "r" );
        while( $data = fread( $fp, 4096 ) ){
            $data = iconv( "GBK", "UTF-8" , $data );
            if( ! xml_parse( $this->_m_xmlParser,  $data, feof($fp) ) ) {
                die( printf("XML error: %s at line %d", 
                    xml_error_string(xml_get_error_code($this->_m_xmlParser)), 
                    xml_get_current_line_number($this->_m_xmlParser)) );
            }
        }
    }
}
$parser = new CNewsXMLParser($file);
$parser->parse_it();
?>
